package ar.edu.sccs.model.similarity;

import java.util.Iterator;

import org.apache.log4j.Logger;

import ar.edu.sccs.entities.Case;
import ar.edu.sccs.entities.Dimension;
import ar.edu.sccs.util.Constants;

public class SimilarityModule {

	static Logger logger = Logger.getLogger(SimilarityModule.class);

	private Case targetCase = null;

	private static SimilarityModule instance = null;

	public static SimilarityModule getInstance() {
		if (instance == null)
			return instance = new SimilarityModule();
		else
			return instance;
	}

	private SimilarityModule() {
	}

	public Case calculateSimilarity(Case targetCase, Case retrievedCase) {
		logger.debug("SimilarityModule.calculateSimilarity");

//		// Grabo en una variable de clase el Caso Base
//		setBaseCase(targetCase);

		// Itero todas las dimensiones
		for (Iterator<String> keys = targetCase.getDimensions().keySet().iterator(); keys.hasNext();) {
			String key = keys.next();
			Dimension targetDimension = targetCase.getDimensions().get(key);
			Dimension retrievedDimension = retrievedCase.getDimensions().get(key);

			switch (targetDimension.getType()) {
			case Constants.Dimension.Type.LIST:
				if (retrievedDimension != null)
					ListSimilarity.getInstance().calculateSimilarity(targetDimension, retrievedDimension);
				break;
			case Constants.Dimension.Type.WORD:
				if (retrievedDimension != null)
					WordSimilarity.getInstance().calculateSimilarity(targetDimension, retrievedDimension);
				break;
			case Constants.Dimension.Type.CLASS:
				if (retrievedDimension != null)
					ClassSimilarity.getInstance().calculateSimilarity(targetDimension, retrievedDimension);
				break;
			case Constants.Dimension.Type.PACKAGE:
				if (retrievedDimension != null)
					PackageSimilarity.getInstance().calculateSimilarity(targetDimension, retrievedDimension);
				break;
			case Constants.Dimension.Type.BOOLEAN:
				if (retrievedDimension != null)
					BooleanSimilarity.getInstance().calculateSimilarity(targetDimension, retrievedDimension);
				break;
			default:
				break;
			}
		}

		return retrievedCase;
	}

	/**
	 * @return the baseCase
	 */
	public Case getBaseCase() {
		return targetCase;
	}

	/**
	 * @param baseCase
	 *            the baseCase to set
	 */
	public void setBaseCase(Case baseCase) {
		this.targetCase = baseCase;
	}
}
